home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************\
- ** XFDES.C - FAST DES ENCRYPTION ALOGRITHM FUNCTIONS FOR TURBO-C **
- ******************************************************************************
- ** VAX/FDES Routines Modified By Doctor Dissector **
- ******************************************************************************
- ** Copyright (c) 1991, By Doctor Dissector Last Update: 03/04/91 **
- \****************************************************************************/
-
- /*
- ** XFDES - Version 1.05
- ** Copyright 1991 By Doctor Dissector
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation; either version 1, or (at your option)
- ** any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- char xfdes_c_msg[]="xfdes v1.05 - 4/3/91 - (c)1991 - filename: xfdes.c";
-
- /*=[ Include Files ]========================================================*/
-
- #include "xfdes.h"
-
- /*=[ Global Variables ]=====================================================*/
-
- /* The C and D arrays used to calculate the key schedule. */
- static obpb1 C[28], D[28];
-
- /* Key schedule. Alternating longs with low and high bits of key.
- ** Low and high 24 bits of keys are stored alternately.
- */
- sbpb24 KS[32];
-
- /* The current block, divided into 2 halves. */
- obpb1 L[32], R[32];
-
- /* Tables that combine the S and P operations. */
- sbpb24 S0L[64], S1L[64], S2L[64], S3L[64],
- S4L[64], S5L[64], S6L[64], S7L[64],
- S0H[64], S1H[64], S2H[64], S3H[64],
- S4H[64], S5H[64], S6H[64], S7H[64];
-
- /* It is slightly faster to indirect through this table than to specify
- ** the desired table directly.
- */
- static sbpb24 *stt[] =
- {
- S0L, S0H,
- S1L, S1H,
- S2L, S2H,
- S3L, S3H,
- S4L, S4H,
- S5L, S5H,
- S6L, S6H,
- S7L, S7H,
- };
-
- /*===========================================================================*/
-
- /* Convert unsl in twenty-four bit contiguous format
- ** to six bits per byte format. Return result.
- */
- static sbpb24
- tfTOsixbit(tf)
- ebpb24 tf;
- {
- sbpb24 res=0;
-
-
- res |= (tf >> 0) & 077;
- res |= (((tf >> 6) & 077) << 8);
- res |= (((tf >> 12) & 077) << 16);
- return(res | (((tf >> 18) & 077) << 24));
- }
-
- /*===========================================================================*/
-
- /* Convert unsl in six bits per byte format
- ** to twenty-four bit contiguous format. Return result.
- */
- static ebpb24
- sixbitTOtf(sb)
- sbpb24 sb;
- {
- ebpb24 res=0;
-
-
- res |= ((sb >> 0) & 077);
- res |= (((sb >> 8) & 077) << 6);
- res |= (((sb >> 16) & 077) << 12);
- return(res | (((sb >> 24) & 077) << 18));
- }
-
- /*===========================================================================*/
-
- /* Set up the key schedule from the key. */
- static void
- fsetkey(key)
- obpb1 *key;
- {
- reg int i, j, k;
- obpb1 s, t;
-
-
- /* First, generate C and D by permuting the key. The low order bit of each
- ** 8-bit char is not used, so C and D are only 28 bits apiece.
- */
- for(i=0; i<28; i++) {
- C[i]=key[PC1_C[i]];
- D[i]=key[PC1_D[i]];
- }
- /* To generate Ki, rotate C and D according to schedule and pick up a
- ** permutation using PC2.
- */
- for(i=0; i<32; i+=2) {
- for(k=0 ; k<shifts[i/2]; k++) { /* rotate */
- s=C[0];
- t=D[0];
- for(j=0; j<27; j++) {
- C[j]=C[j+1];
- D[j]=D[j+1];
- }
- C[27]=s;
- D[27]=t;
- }
- /* Get Ki. Note C and D are concatenated. */
- KS[i]=KS[i+1]=0;
- for(j=0; j<24; j++) {
- KS[i] |= ((sbpb24) C[PC2_C[j]] << j);
- KS[i+1] |= ((sbpb24) D[PC2_D[j]] << j);
- }
- KS[i]=tfTOsixbit(KS[i]);
- KS[i+1]=tfTOsixbit(KS[i+1]);
- }
- }
-
- /*===========================================================================*/
-
- /* Lookup an S-box entry.*/
- static fbpb4
- lookupS(tableno, t6bits)
- unsl tableno;
- sbpb6R t6bits;
- {
- sbpb6 fixed6bits;
- fbpb4R r;
- fbpb4 fixedr;
-
-
- fixed6bits=(((t6bits >> 0) & 01) << 5)+
- (((t6bits >> 1) & 01) << 3)+
- (((t6bits >> 2) & 01) << 2)+
- (((t6bits >> 3) & 01) << 1)+
- (((t6bits >> 4) & 01) << 0)+
- (((t6bits >> 5) & 01) << 4);
- r=(fbpb4)S[(int)tableno][(int)fixed6bits];
- fixedr=(((r >> 3) & 01) << 0)+
- (((r >> 2) & 01) << 1)+
- (((r >> 1) & 01) << 2)+
- (((r >> 0) & 01) << 3);
- return(fixedr);
- }
-
- /*===========================================================================*/
-
- /* The payoff: encrypt a block. */
- static void
- xform(quarters, saltvalue)
- sbpb24 *quarters;
- sbpb24 saltvalue;
- {
- reg sbpb6 *dp;
- reg int mi;
- reg sbpb24 *kp, *kend, k;
- static sbpb24 Dl, Dh;
- sbpb24 Rl, Rh, Ll, Lh, negsalt;
-
-
- negsalt = ~saltvalue;
- Ll=Lh=Rl=Rh=0;
- kend=&KS[32];
- for(mi=24; mi>-1; mi--) {
- for(kp=KS; kp<kend; ) {
- reg sbpb24 **stp;
- k=(Rl ^ Rh);
- k &= (~negsalt);
- Dl=(k ^( Rl ^ *kp++));
- Dh=(k ^( Rh ^ *kp++));
- stp=((sbpb24 **) stt);
- dp=((sbpb6 *) & Dl);
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- dp=((sbpb6 *) & Dh);
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- Ll ^= (*stp++)[*dp];
- Lh ^= (*stp++)[*dp++];
- k=(Ll ^ Lh);
- k &= (~negsalt);
- Dl=(k ^ Ll ^ *kp++);
- Dh=(k ^ Lh ^ *kp++);
- stp=((sbpb24 **) stt);
- dp=((sbpb6 *) & Dl);
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- dp=((sbpb6 *) & Dh);
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- Rl ^= (*stp++)[*dp];
- Rh ^= (*stp++)[*dp++];
- }
- Ll ^= Rl;
- Lh ^= Rh;
- Rl ^= Ll;
- Rh ^= Lh;
- Ll ^= Rl;
- Lh ^= Rh;
- }
- {
- reg sbpb24 *qp;
-
-
- qp=quarters;
- *qp++=Ll;
- *qp++=Lh;
- *qp++=Rl;
- *qp++=Rh;
- }
- }
-
- /*===========================================================================*/
-
- /* Final permutation. Takes input from globals L and R. */
- static void
- Fperm(block)
- unsb *block;
- {
- reg int j, k;
-
-
- for(j=0; j<64; j++) {
- k=FP[j];
- block[j]=((k<32) ? L[k] : R[k-32]);
- }
- }
-
- /*===========================================================================*/
-
- /* Inverse of E permutation. */
- static void
- undoe(fromarr, toarr)
- obpb1 *fromarr, *toarr;
- {
- reg int j;
-
-
- for(j=0; j<32; j++)
- toarr[j]=fromarr[1+(j & 03)+6*(j >> 2)];
- }
-
- /*===========================================================================*/
-
- static void
- toBA64(quarters, onebits64)
- reg sbpb24 *quarters;
- obpb1 *onebits64;
- {
- int j;
- static obpb1 tmpE[48];
- reg unsb *onebits48;
- reg sbpb24 quarter;
-
-
- onebits48=tmpE;
- quarter=sixbitTOtf(*quarters++);
- for(j=0; j<24; j++)
- *onebits48++=((quarter >> j) & 01);
- quarter=sixbitTOtf(*quarters++);
- for(j=0; j<24; j++)
- *onebits48++=((quarter >> j) & 01);
- undoe(tmpE,L);
- onebits48=tmpE;
- quarter=sixbitTOtf(*quarters++);
- for(j=0; j<24; j++)
- *onebits48++=((quarter >> j) & 01);
- quarter=sixbitTOtf(*quarters++);
- for(j=0; j<24; j++)
- *onebits48++=((quarter >> j) & 01);
- undoe(tmpE,R);
- Fperm(onebits64);
- }
-
- /*===========================================================================*/
-
- static char *
- fcrypt(pw, salt)
- const char *pw;
- char *salt;
- {
- reg int i;
- reg obpb1 j, c;
- static obpb1 block[66];
- static char iobuf[16];
- static sbpb24 out96[4];
- sbpb24 saltvalue=0;
-
-
- for(i=0; i<66; i++)
- block[i]=0;
- for(i=0; ((c=*pw)!=NULL) && (i<64); pw++) {
- for(j=0; j<7; j++, i++)
- block[i]=((c >> (6-j)) & 01);
- i++;
- }
- fsetkey(block);
- for(i=0; i<2; i++) {
- c=iobuf[i]=*salt++;
- if (c>'Z')
- c-=6;
- if (c>'9')
- c-=7;
- c-='.';
- for(j=0; j<6; j++)
- saltvalue |= ((c >> j) & 01) << (6*i+j);
- }
- saltvalue=tfTOsixbit(saltvalue);
- xform(out96, saltvalue);
- toBA64(out96, block);
- for(i=0; i<11; i++) {
- c=0;
- for(j=0; j<6; j++) {
- c <<= 1;
- c |= block[6*i+j];
- }
- c+='.';
- if (c>'9')
- c+=7;
- if (c>'Z')
- c+=6;
- iobuf[i+2]=c;
- }
- iobuf[i+2]=0;
- if (!iobuf[1])
- iobuf[1]=iobuf[0];
- return(iobuf);
- }
-
- /*===========================================================================*/
-
- static void
- init(tableno, lowptr, highptr)
- unsl tableno;
- sbpb24 *lowptr, *highptr;
- {
- reg int k, i;
- static obpb1 tmp32[32];
- static obpb1 tmpP32[32];
- static obpb1 tmpE[48];
- sbpb6R j;
-
-
- for(j=0; j<64; j++) {
- k=lookupS(tableno, j);
- for(i=0; i<32; i++)
- tmp32[i]=0;
- for(i=0; i<4; i++)
- tmp32[4*(int)tableno+i]=(obpb1)(k >> i) & 01;
- for(i=0; i<32; i++)
- tmpP32[i]=tmp32[P[i]-1];
- for(i=0; i<48; i++)
- tmpE[i]=tmpP32[(int)E[i]-1];
- lowptr[j]=highptr[j]=0;
- for(i=0; i<24; i++)
- lowptr[(int)j] |= (unsl)tmpE[i] << i;
- for(k=0, i=24; i<48; i++, k++)
- highptr[(int)j] |= (unsl)tmpE[i] << k;
- lowptr[j]=tfTOsixbit(lowptr[j]);
- highptr[j]=tfTOsixbit(highptr[j]);
- }
- }
-
- /*===========================================================================*/
-
- static void
- init_des(void)
- {
- init((unsl)0, S0L, S0H);
- init((unsl)1, S1L, S1H);
- init((unsl)2, S2L, S2H);
- init((unsl)3, S3L, S3H);
- init((unsl)4, S4L, S4H);
- init((unsl)5, S5L, S5H);
- init((unsl)6, S6L, S6H);
- init((unsl)7, S7L, S7H);
- }
-